<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-touch-fullscreen" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <title>learn-PixiJS</title>
</head>
<body>

<div>
    <button onclick="startPlay()">开始播放</button>
    <button onclick="playContinue()">继续播放视频</button>
    <button onclick="stopPlay()">暂停播放</button>
</div>
<div>
    <button onclick="renderOrigin()">原色</button>
    <button onclick="renderInverse()">反色</button>
    <button onclick="renderEmboss()">绘制浮雕</button>
    <button onclick="renderEdge()">绘制边缘</button>
</div>
<script src="js/pixi.min.js"></script>

<script>

  const fragmentSrc_origin = `
 precision mediump float;

 // the texCoords passed in from the vertex shader.
 varying vec2 v_texCoord;

 // our texture
 uniform sampler2D uSampler2;

 void main(){
   // Look up a color from the texture.
   gl_FragColor = texture2D(uSampler2, v_texCoord).rgba;
 }
`;

  // 反色
  const fragmentSrc_inverse = `
 precision mediump float;

 // the texCoords passed in from the vertex shader.
 varying vec2 v_texCoord;

 // our texture
 uniform sampler2D uSampler2;

 void main(){
   // Look up a color from the texture.
   gl_FragColor = texture2D(uSampler2, v_texCoord).bgra;
 }
`;
  // 绘制浮雕
  const fragmentSrc_emboss = `
//浮雕效果:
precision mediump float;
varying vec2 v_texCoord;
uniform sampler2D uSampler2;
uniform vec2 steps;
const float stride = 2.0;
void main()
{

    vec3 tmpColor = texture2D(uSampler2, v_texCoord + steps * stride).rgb;
    tmpColor = texture2D(uSampler2, v_texCoord).rgb - tmpColor + 0.5;
    float f = (tmpColor.r + tmpColor.g + tmpColor.b) / 3.0;
    gl_FragColor = vec4(f, f, f, 1.0);
}
`;

  // 绘制边缘
  const fragmentSrc_edge = `
//浮雕效果:
precision mediump float;
varying vec2 v_texCoord;
uniform sampler2D uSampler2;
uniform vec2 steps;
const float stride = 2.0;
void main()
{

    vec3 tmpColor = texture2D(uSampler2, v_texCoord + steps * stride).rgb;
    tmpColor = abs(texture2D(uSampler2, v_texCoord).rgb - tmpColor);
    gl_FragColor = vec4(tmpColor * 2.0, 1.0);
}
`;
  // 片段着色起
  let fragmentSrc = fragmentSrc_origin;
  let uniforms_steps = [];


  const Loader = PIXI.Loader.shared,
    Resources = PIXI.loader.resources,
    TextureCache = PIXI.utils.TextureCache;


  const videoUrl = 'media/video.mp4';
  const imgUrl = 'images/vocaloid.jpg';
  let videoTexture = null; // 视频纹理

  const global = {
    timer: null
  };

  // 绘制原色
  function renderOrigin() {
    fragmentSrc = fragmentSrc_origin;
    reStart()
  };
  // 绘制反色
  function renderInverse() {
    fragmentSrc = fragmentSrc_inverse;
    reStart()
  };
  // 绘制浮雕
  function renderEmboss() {
    fragmentSrc = fragmentSrc_emboss;
    // 由于浮雕效果需要知道采样步长，所以传递此参数给shader。
    // [1.0 / canvas.width, 1.0 / canvas.height]
    uniforms_steps = [1.0 / 540, 1.0 / 540];
    reStart()
  };

  // 绘制边缘
  function renderEdge() {
    fragmentSrc = fragmentSrc_edge;
    // 由于绘制边缘效果需要知道采样步长，所以传递此参数给shader。
    uniforms_steps = [1.0 / 540, 1.0 / 540];
    reStart()
  };


  // 重新开始
  function reStart() {
//    onPlayVideo();
    clearTimeout(global.timer);
    App.filterChange()
  }

  function stopPlay() {
    if (videoTexture) {
      videoTexture.baseTexture.source.pause();
    }
  }

  function playContinue() {
    if (videoTexture) {
      videoTexture.baseTexture.source.play();
    }
  }


  var App = {
    geometry: null,
    init: function () {
      const picArr = [];

      picArr.push(videoUrl);
      picArr.push(imgUrl);
      for (let i = 0; i < 71; i++) {
        const texture = (`images/1X1/S1a_${i}.png`);
        picArr.push(texture);
      }
      for (let i = 0; i < 63; i++) {
        const texture = (`images/1X1/S1b_${i}.png`);
        picArr.push(texture);
      }
      for (let i = 0; i < 15; i++) {
        const texture = (`images/1X1/S1c_${i}.png`);
        picArr.push(texture);
      }

      window.app = new PIXI.Application({
        backgroundColor: 0x1099bb,
        width: 540,
        height: 540,
      });
      document.body.appendChild(app.view);

      // 加载资源
      Loader
        .add(picArr)
        .on("progress", this.loadProgressHandler)
        .load(this.onAssetsLoaded.bind(this));
    },
    // 资源加载进度
    loadProgressHandler: function (loader, resources) {
      console.log('loading progress: ', loader.progress.toFixed(2) / 1)
    },
    // 资源加载完毕
    onAssetsLoaded: function (loader, resources) {
      console.log("All files loaded");
      this.createVideoTexture();
    },
    // 创建视频纹理
    createVideoTexture: function () {
      videoTexture = PIXI.Texture.from(videoUrl)
    },
    // 开始播放
    startPlay: function () {
      app.stage.removeChildren();
      this.geometry = this.createGeometry();

      videoTexture = TextureCache[videoUrl]; // 暂时没有视频缓存
      videoTexture.baseTexture.currentTime = 0;
      videoTexture.baseTexture.source.play();
//      const videoSprite = new PIXI.Sprite(videoTexture);
//      videoSprite.width = app.screen.width;
//      videoSprite.height = app.screen.height;
//      app.stage.addChild(videoSprite);
      const anim = this.createImages();
      anim.play();
      app.stage.addChild(this.geometry);

      const text = this.createText();
      const text2 = this.createText2();

//      text.height = 0;


      app.stage.addChild(anim);
      app.stage.addChild(text);
      app.stage.addChild(text2);

      global.timer = setTimeout(() => {
        anim.stop();
        videoTexture.baseTexture.source.pause();
        videoTexture.update();

      }, 6000);

    },
    createImages: function () {
      const frames = [];

      for (let i = 0; i < 71; i++) {
        const texture = TextureCache[`images/1X1/S1a_${i}.png`];
        frames.push(texture);
      }
      for (let i = 0; i < 63; i++) {
        const texture = TextureCache[`images/1X1/S1b_${i}.png`];
        frames.push(texture);
      }
      for (let i = 0; i < 15; i++) {
        const texture = TextureCache[`images/1X1/S1c_${i}.png`];
        frames.push(texture);
      }
      const anim = new PIXI.AnimatedSprite(frames);
      anim.x = 0;
      anim.y = 0;
//    anim.anchor.set(0.5); // 原点
      anim.animationSpeed = 0.4; // 速度 24 / 60 = 0.4
      return anim
    },
    createText: function () {
      const style = new PIXI.TextStyle({
        fontFamily: 'Arial',
        fontSize: 36,
//      fontStyle: 'italic',
        fontWeight: 'bold',
//        fill: ['#ffffff', '#00ff99'], // gradient
        fill: ['#ffffff'], // gradient
//        stroke: '#4a1850',
//        strokeThickness: 5,
//        dropShadow: true,
//        dropShadowColor: '#000000',
//        dropShadowBlur: 4,
//        dropShadowAngle: Math.PI / 6,
//        dropShadowDistance: 6,
        wordWrap: true,
        wordWrapWidth: 440,
      });

      const richText = new PIXI.Text('挑战你的极限', style);

      const container_x = (app.screen.width - richText.width) / 2;
      const container_y = 200;
      richText.x = 0;
      richText.y = -richText.height;
      let container = new PIXI.Container();
      container.addChild(richText);
      container.x = container_x;
      container.y = container_y;

      const timer = setInterval(() => {
        richText.y = richText.y + 2;
        if (richText.y > 0) {
          clearInterval(timer)
        }
      }, 70);


      const graphics = new PIXI.Graphics();
      graphics.beginFill(0xFF3300);
      graphics.drawRect(container_x, container_y, richText.width, richText.height);
      graphics.endFill();

//      const sprite = new PIXI.Sprite(texture);
      container.mask = graphics;

      return container
    },
    createText2: function () {
      const style = new PIXI.TextStyle({
        fontFamily: 'Arial',
        fontSize: 28,
//        lineHeight: 40,
        fontWeight: 'bold',
        fill: ['#03e1d1'], // gradient
        wordWrap: true,
        wordWrapWidth: 440,
//        padding: 20
      });

      const richText = new PIXI.Text('FITNESS', style);

      const container_x = (app.screen.width - richText.width) / 2;
      const container_y = 250;

      // 绘制背景
      const bg_color = new PIXI.Graphics();
      bg_color.beginFill(0x000000);
      bg_color.drawRect(0, 0, richText.width, richText.height);
      bg_color.endFill();
      let container = new PIXI.Container();


      container.addChild(bg_color);
      container.addChild(richText);
      container.x = container_x;
      container.y = container_y;


      const mask_graphics = new PIXI.Graphics();

      mask_graphics.lineStyle(4, 0xFF3300, 1);
      mask_graphics.beginFill(0x66CCFF);

//      mask_graphics.drawRect(container_x - 15, container_y, richText.width, richText.height);
      mask_graphics.drawRect(0, 0, richText.width, richText.height);


      mask_graphics.endFill();
      container.addChild(mask_graphics);

      container.mask = mask_graphics;
//      mask_graphics.x = 30;
//      mask_graphics.y = 30;

      mask_graphics.x = container.width / 2;
      mask_graphics.y = 0;
      mask_graphics.width = 0;

      const timer = setInterval(() => {
        mask_graphics.width = mask_graphics.width + 2;
        mask_graphics.x = (richText.width - mask_graphics.width) / 2;
        if (mask_graphics.width > richText.width) {
          clearInterval(timer)
        }
      }, 100);
      return container
    },
    createGeometry: function () {
      const geometry = new PIXI.Geometry()
        .addAttribute('aVertexPosition', // the attribute name
          [-1, -1, // x, y
            1, -1, // x, y
            -1, 1,
            1, 1], // x, y], // x, y
          2) // the size of the attribute

        .addAttribute('aColor', // the attribute name
          [1, 0, 0, // r, g, b
            0, 1, 0, // r, g, b
            0, 0, 1], // r, g, b
          3) // the size of the attribute

        .addIndex([0, 1, 2, 1, 2, 3]);

      const vertexSrc = `

 precision mediump float;
    attribute vec4 aVertexPosition;

    varying vec2 v_texCoord;
    void main()
    {
        gl_Position = aVertexPosition;
        // v_texCoord = aPosition;
        // v_texCoord = vec2((aVertexPosition.x), (1.0-aPosition.y));
        // 这是一种取巧的做法，强行把顶点坐标映射为纹理坐标，
        // 但是仅适用于本章用到的刚好占满整个viewport的顶点哦。
        v_texCoord = vec2((aVertexPosition.x+1.0)/2.0, 1.0-(aVertexPosition.y+1.0)/2.0);;
    }`;

//    const fragmentSrc = `
// precision mediump float;
//
// // the texCoords passed in from the vertex shader.
// varying vec2 v_texCoord;
//
// // our texture
// uniform sampler2D uSampler2;
//
// void main(){
//   // Look up a color from the texture.
//   gl_FragColor = texture2D(uSampler2, v_texCoord).bgra;
// }
//`;


      const uniforms = {
//      uSampler2: TextureCache[imgUrl],
        uSampler2: TextureCache[videoUrl],
//      steps: 1.0 / canvas.width, 1.0 / canvas.height,
        steps: uniforms_steps || [],
        time: 0,
      };

      const shader = PIXI.Shader.from(vertexSrc, fragmentSrc, uniforms);

      const triangle = new PIXI.Mesh(geometry, shader);
      triangle.position.set(400, 300);
      triangle.scale.set(2);

      return triangle;
    },
    // 滤镜发生改变
    filterChange: function () {
      this.startPlay()
    }
  }
  App.init();
  function startPlay() {
    App.startPlay()
  }
</script>
</body>
</html>